<template>
  <a-card :bordered="false" style="width: 100%">
    <!-- 自定义顶部搜索 -->
    <template #title>
      <div style="display: flex">
        <a-row class="a-row-search" :gutter="16">
          <a-col :lg="8">
            <span>菜单名称：</span>
            <a-input
              style="width: 200px"
              v-model:value="searchMenu.title"
              placeholder="菜单名称"
            ></a-input>
          </a-col>
          <a-col :lg="8">
            <span>菜单类型：</span>
            <a-select
              placeholder="菜单类型"
              ref="select"
              v-model:value="searchMenu.type"
              style="width: 200px"
              @change="handleChange"
            >
              <a-select-option :value="0">目录</a-select-option>
              <a-select-option :value="1">菜单</a-select-option>
              <a-select-option :value="2">按钮</a-select-option>
            </a-select>
          </a-col>
          <a-col :lg="8">
            <span>菜单状态：</span>
            <a-select
              placeholder="菜单状态"
              ref="select"
              v-model:value="searchMenu.status"
              style="width: 200px"
              @change="handleChange"
              :options="statusData"
            />
          </a-col>
        </a-row>
        <div class="right-btn">
          <a-space :size="40">
            <a-button
              type="primary"
              v-permission="`permission:menu:query`"
              @click="handleSearch"
              >查询</a-button
            >
            <a-button
              @click="handleReset"
              v-permission="`permission:menu:reset`"
              >重置</a-button
            >
          </a-space>
        </div>
      </div>
    </template>

    <!-- 新增菜单区域 -->
    <div style="height: 60px">
      <a-button
        type="primary"
        v-permission="`permission:menu:add`"
        @click="handlerAddDicMenuOpen"
      >
        <template #icon>
          <PlusCircleOutlined spin />
        </template>
        新增
      </a-button>
    </div>

    <!-- 菜单表格数据 -->
    <a-table
      :scroll="{ x: 1500 }"
      :dataSource="tableData"
      :loading="loading"
      :pagination="false"
    >
      <a-table-column
        fixed="left"
        title="菜单编号"
        dataIndex="id"
        :width="100"
      />
      <a-table-column
        fixed="left"
        title="组件名称"
        dataIndex="name"
        :width="120"
      />
      <a-table-column title="菜单名称" dataIndex="title" :width="120" />
      <a-table-column title="类型" dataIndex="type" :width="100">
        <template #default="{ record }">
          <a-tag color="cyan" v-if="record.type === 0">目录</a-tag>
          <a-tag color="blue" v-if="record.type === 1">菜单</a-tag>
          <a-tag color="purple" v-if="record.type === 2">按钮</a-tag>
        </template>
      </a-table-column>
      <a-table-column title="权限标识" dataIndex="permission" :width="160" />
      <a-table-column title="组件路径" dataIndex="component" :width="160" />
      <a-table-column title="状态" dataIndex="status" :width="100">
        <template #default="{ record }">
          <a-tag :color="record.status === 1 ? '#108ee9' : '#cd201f'">{{
            record.status === 1 ? "开启" : "关闭"
          }}</a-tag>
        </template>
      </a-table-column>
      <a-table-column fixed="right" title="操作" :width="165">
        <template #default="{ record }">
          <a-button
            :disabled="record.type === 2 ? true : false"
            type="link"
            size="small"
            @click="handlerAddMenuOpen(record.title)"
            v-permission="`permission:menu:add`"
          >
            <PlusCircleOutlined spin />
            新增
          </a-button>
          <a-button
            v-permission="`permission:menu:update`"
            type="link"
            size="small"
            @click="handleEchoMenu(record.id)"
          >
            <FormOutlined />
            修改
          </a-button>
          <a-popconfirm
            placement="bottom"
            ok-text="确认"
            cancel-text="取消"
            title="确认删除该菜单？"
            @confirm="handleRemoveMenu(record.id)"
          >
            <a-button
              v-permission="`permission:menu:delete`"
              type="link"
              danger
              size="small"
            >
              <DeleteOutlined />
              删除
            </a-button>
          </a-popconfirm>
        </template>
      </a-table-column>
    </a-table>
  </a-card>

  <!-- 新增菜单弹框 -->
  <a-modal
    @cancel="handlerCancel"
    v-model:open="addMenuOpen"
    width="30%"
    :title="menu.id === undefined ? '添加菜单' : '修改菜单'"
    @ok="handleOk"
  >
    <a-form
      ref="formRef"
      :rules="rules"
      :model="menu"
      :wrapper-col="wrapperCol"
      :labelCol="labelCol"
    >
      <a-form-item v-if="isDic" ref="parent" label="上级菜单" name="parent">
        <a-input disabled v-model:value="menu.parent" />
      </a-form-item>
      <a-form-item v-else ref="parent" label="上级菜单" name="parent">
        <a-input disabled v-model:value="menu.parent" />
      </a-form-item>
      <a-form-item label="菜单类型" name="type">
        <a-radio-group v-model:value="menu.type">
          <a-radio :value="0" v-if="isDic">目录</a-radio>
          <a-radio :value="1" @click="handleMenu" v-if="isBtn">菜单</a-radio>
          <a-radio :value="2" @click="handleBtn" v-if="isBtn">按钮</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-form-item v-if="hasName" ref="name" label="组件名称" name="name">
        <a-input
          placeholder="大写字母开头，如：Permission"
          v-model:value="menu.name"
        />
      </a-form-item>
      <a-form-item ref="title" label="菜单名称" name="title">
        <a-input
          :placeholder="hasName ? '如：权限管理' : '如：用户删除'"
          v-model:value="menu.title"
        />
      </a-form-item>
      <a-form-item
        v-if="isBtn"
        ref="permission"
        label="权限标识"
        name="permission"
      >
        <a-input
          placeholder="如：permission:user:add"
          v-model:value="menu.permission"
        />
      </a-form-item>
      <a-form-item
        v-if="isBtnEdit"
        ref="component"
        label="组件路径"
        name="component"
      >
        <a-input
          placeholder="如：/permission/user/index"
          v-model:value="menu.component"
        />
      </a-form-item>
      <a-form-item label="菜单状态" name="status">
        <a-radio-group v-model:value="menu.status" :options="statusData" />
      </a-form-item>
    </a-form>

    <template #footer>
      <a-button
        key="submit"
        type="primary"
        :loading="saveLoading"
        @click="handleSaveMenu"
        >确定</a-button
      >
      <a-button key="back" @click="handlerCancel">取消</a-button>
    </template>
  </a-modal>
</template>

<script setup>
import { ref, onMounted } from "vue";
import {
  queryMenuList,
  queryMenuListByLike,
  addMenu,
  removeMenu,
  echoMenu,
  updateMenu,
} from "@/api/menu";
import { message } from "ant-design-vue";
import { verifyMenuName } from "@/util/regexutils";
import { queryDictLabel } from "@/api/dict_data";
import { MENU_CONSTANT } from "@/constant/dictType.js";

//加载中状态
const loading = ref(true);
const saveLoading = ref(false);
//新增菜单弹框
const addMenuOpen = ref(false);
const tableData = ref([]);
const isDic = ref(false);
const isBtn = ref(false);
const isBtnEdit = ref(false);
const hasName = ref(true);
const menu = ref({});
const searchMenu = ref({
  title: "",
  type: null,
  status: null,
});
const statusData = ref([]);

onMounted(() => {
  getMenuList();
  getDictTypeStatus();
});

//获取菜单树形数据
const getMenuList = () => {
  queryMenuList().then((res) => {
    if (res.code === 200) {
      tableData.value = res.data;
      loading.value = false;
    }
  });
};

//模糊查询
const getMenuListByLike = () => {
  queryMenuListByLike(searchMenu.value).then((res) => {
    if (res.code === 200) {
      tableData.value = res.data;
      loading.value = false;
    }
  });
};

//查询字典状态
const getDictTypeStatus = () => {
  queryDictLabel(MENU_CONSTANT).then((res) => {
    if (res.code === 200) {
      statusData.value = res.data;
    }
  });
};

//新增菜单弹框取消回调
const handlerCancel = () => {
  addMenuOpen.value = false;
  menu.value = {};
  tempParent.value = "";
};

//新增菜单弹框
const tempParent = ref("");
const handlerAddMenuOpen = (item) => {
  isBtnEdit.value = true;
  isBtn.value = true;
  isDic.value = false;
  addMenuOpen.value = true;
  tempParent.value = item;
  menu.value.parent = ref(item);
};

//新增目录弹框
const handlerAddDicMenuOpen = () => {
  isBtnEdit.value = false;
  isDic.value = true;
  isBtn.value = false;
  addMenuOpen.value = true;
  hasName.value = true;
  menu.value.parent = ref("主类目");
};

//新增、修改菜单
const handleSaveMenu = () => {
  formRef.value.validate().then(() => {
    //校验菜单权限标识和组件路径是否符合规范
    try {
      verifyMenuName(menu.value);
    } catch (error) {
      message.error(error.message);
      return;
    }
    saveLoading.value = true;
    if (menu.value.id === undefined) {
      //新增菜单
      addMenu(menu.value).then((res) => {
        if (res.code === 200) {
          message.success("新增成功！");
          addMenuOpen.value = false;
          saveLoading.value = false;
          menu.value = {};
          getMenuList();
        } else {
          saveLoading.value = false;
        }
      });
    } else {
      //修改菜单
      updateMenu(menu.value).then((res) => {
        if (res.code === 200) {
          message.success("修改成功！");
          addMenuOpen.value = false;
          saveLoading.value = false;
          menu.value = {};
          getMenuList();
        } else {
          saveLoading.value = false;
        }
      });
    }
  });
};

//点击菜单时
const handleMenu = () => {
  isDic.value = false;
  isBtn.value = true;
  isBtnEdit.value = true;
  hasName.value = true;
  menu.value = ref({});
  menu.value.parent = ref(tempParent.value);
};

//点击按钮时
const handleBtn = () => {
  isDic.value = false;
  isBtn.value = true;
  isBtnEdit.value = false;
  hasName.value = false;
  menu.value = ref({});
  menu.value.parent = ref(tempParent.value);
};

//回显菜单数据
const handleEchoMenu = (id) => {
  echoMenu(id).then((res) => {
    if (res.code === 200) {
      menu.value = res.data;
      if (menu.value.type === 0) {
        isDic.value = true;
        hasName.value = true;
        isBtn.value = false;
        isBtnEdit.value = false;
        addMenuOpen.value = true;
      } else if (menu.value.type === 1) {
        isDic.value = false;
        isBtn.value = true;
        isBtnEdit.value = true;
        hasName.value = true;
        addMenuOpen.value = true;
      } else {
        isDic.value = false;
        isBtn.value = true;
        isBtnEdit.value = false;
        hasName.value = false;
        addMenuOpen.value = true;
      }
    }
  });
};

//删除菜单
const handleRemoveMenu = (id) => {
  removeMenu(id).then((res) => {
    if (res.code === 200) {
      message.success("菜单删除成功！");
      getMenuList();
    }
  });
};

//重置
const handleReset = () => {
  searchMenu.value = {
    title: "",
    type: null,
    status: null,
  };
  getMenuList();
};

//搜索
const handleSearch = () => {
  if (
    searchMenu.value.title !== "" ||
    searchMenu.value.type !== null ||
    searchMenu.value.status !== null
  ) {
    getMenuListByLike();
  }
};

const labelCol = {
  span: 6,
};
const wrapperCol = {
  span: 16,
};

const formRef = ref();
const rules = ref({
  name: [
    {
      required: true,
      message: "请输入组件名称",
      trigger: "change",
    },
  ],
  title: [
    {
      required: true,
      message: "请输入菜单名称",
      trigger: "change",
    },
  ],
  type: [
    {
      required: true,
      message: "请选择菜单类型",
      trigger: "change",
    },
  ],
  status: [
    {
      required: true,
      message: "请选择菜单状态",
      trigger: "change",
    },
  ],
  permission: [
    {
      required: true,
      message: "请输入权限标识",
      trigger: "change",
    },
  ],
  component: [
    {
      required: true,
      message: "请输入组件路径",
      trigger: "change",
    },
  ],
});
</script>
<style scoped lang='scss'>
.a-row-search {
  height: 100px;
  width: 85%;
  display: flex;
  align-items: center;
}
.right-btn {
  width: 15%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
</style>